<?php

    /**
     * @package      Modules
     * @subpackage   Base_Classes_Utils
     *
     * @license      GNU Lesser General Public Licence see LICENCE-LGPL file or http://www.gnu.org/licenses/lgpl.html
     */
    class Base_Classes_Utils_SlugCache
    {

    ////////////////////////////////////////////////////////////////////////////
    //                               Variables                                //
    ////////////////////////////////////////////////////////////////////////////

        /**
         * Model's name
         *
         * @var     string
         */
        protected $_model       = null;

        /**
         * Slug's field name
         *
         * @var     string
         */
        protected $_fieldName   = null;

        /**
         * List of slugs in cache
         *
         * @var     array|null
         */
        protected $_list        = null;

    ////////////////////////////////////////////////////////////////////////////
    //                                 Methods                                //
    ////////////////////////////////////////////////////////////////////////////

        /**
         * Constructor
         *
         * @param       string      $model
         * @param       string      $fieldName
         */
        public function __construct($model, $fieldName = 'slug')
        {
            $this->_model       = $model;
            $this->_fieldName   = $fieldName;

            $this->_buildSlugsCache();
        }

        /**
         * Builds slugs cache
         *
         * @return      void
         */
        private function _buildSlugsCache()
        {
            if (is_null($this->_list)) {
                $this->_list    = Doctrine_Query::create()
                                    ->select($this->_fieldName)
                                    ->from($this->_model . ' m INDEXBY m.' . $this->_fieldName)
                                    ->execute(array(), Doctrine::HYDRATE_ARRAY);
            }
        }

        /**
         * Adds the slug to the array in cache
         *
         * @param   string  $slug
         * @return  void
         */
        public function add($slug)
        {
            if (isset($this->_list[$slug])) {

                // The slug already exists
                throw new Exception('Slug already exists.');
                
            } else {

                $this->_list[$slug] = $slug;
            }
        }

        /**
         * Returns the slug in cache
         *
         * @param   string      $slug
         * @return  string|null
         */
        public function get($slug)
        {
            return $this->_list[$slug];
        }

        /**
         * Returns true if the slug is already in cache
         *
         * @param   string      $slug
         * @param   int|null    $iterator
         * @return  boolean
         */
        public function exists($slug, $iterator = 0)
        {
            return isset($this->_list[$this->_buildSlug($slug, $iterator)]);
        }

        /**
         * Returns an unique slug
         *
         * @param   string      $from
         * @param   boolean     $add
         * @param   int         $iterator
         */
        public function getUniqueSlug($slug, $add = true, $iterator = 0)
        {
            if ($this->exists($slug, $iterator)) {
                return $this->getUniqueSlug($slug, $add, ++$iterator);
            } else {
                $uniqueSlug = $this->_buildSlug($slug, $iterator);

                if ($add) {
                    // Add automatically in the cache list
                    $this->add($uniqueSlug);
                }

                return $uniqueSlug;
            }
        }

        /**
         * Builds the slug name from name and iterator number
         *
         * @param   string      $slug
         * @param   int         $iterator
         * @return  string
         */
        private function _buildSlug($slug, $iterator = 0)
        {
            if ($iterator == 0) {
                return $slug;
            } else {
                return $slug . '-' . $iterator;
            }
        }
    }